package com.project.common.screens;

import interfaces.IAppManager;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.ExecutionException;

import service.IMService;
import teacher.Attendance;
import teacher.LauncherTeacher;
import teacher.MySchedules;
import teacher.NewSchedule;
import ui.FriendList;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.PixelFormat;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;
import classroom.LauncherStudent;
import classroom.OverAllRating;

import com.project.institute.DAO.Institute;
import com.project.trac.R;

import core.modules.DatabaseConnector;
import finder.ActivityManager;

public class Dashboard extends Institute implements OnItemClickListener {
	
	private GridView menu;
	
	private String[] MENU_STUDENT = 
		{ "Class Schedules", "My Classes", "Messenger" , "My Class Ratings" };
	
	private String[] MENU_TEACHER = 
		{ "New Schedule", "My Classes", "Messenger", "Forum", "Attendance"};
	
	private Integer[] ICONSET_STUDENT = {
			R.drawable.menu_home,
			R.drawable.classes_student,
			R.drawable.menu_messaging,
			R.drawable.menu_ratings
	};
	
	private Integer[] ICONSET_TEACHER = {
			R.drawable.menu_new_schedule,
			R.drawable.classes_teacher,
			R.drawable.menu_messaging,
			R.drawable.sign_information,
			R.drawable.book
	};
	
	private int approval;
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.commons_dashboard_panel);
		setTitle(getFirstName() + "'s Dashboard");
		
		/*
         * Start and bind the imService 
         **/
    	startService(new Intent(Dashboard.this, IMService.class));
		
		menu = (GridView) findViewById(R.id.Menu);
		menu.setOnItemClickListener(this);

		Toast.makeText(getBaseContext(), "Welcome, " + getFirstName() + "!", Toast.LENGTH_LONG).show();
		
	}

	private class MenuItem extends ArrayAdapter<Object> {
		
		public MenuItem(Context context, int textViewResourceId, String[] objects) {
			super(context, textViewResourceId, objects);
		}
		
		public View getView(int position, View convertView, ViewGroup parent) {
			
			LayoutInflater inflater = getLayoutInflater();
			View row = inflater.inflate(R.layout.commons_dashboard_panel_item, parent, false);
			TextView tv = (TextView) row.findViewById(R.id.text);
			
			switch(getRole()) {
			
			case 0:
					if (position == 1) {
						
						if (approval > 0) {
							tv.setText(MENU_TEACHER[position] + " (" + approval + ")");
							tv.setTextColor(getResources().getColor(R.color.custom_red));
						} else {
							tv.setText(MENU_TEACHER[position]);
						}
						
					} else {
						tv.setText(MENU_TEACHER[position]);
					}
					
					tv.setCompoundDrawablesWithIntrinsicBounds(0, ICONSET_TEACHER[position], 0, 0);
				break;
			case 1:
					tv.setText(MENU_STUDENT[position]);
					tv.setCompoundDrawablesWithIntrinsicBounds(0, ICONSET_STUDENT[position], 0, 0);
				break;
			}
			
			return row;
		}
	}

	@Override
	public void onItemClick(AdapterView<?> av, View view, int position, long id) {
		
		if (getRole() == 0) {
			switch (position) {
				case 0:
					startActivity(new Intent(Dashboard.this, NewSchedule.class));
					break;
				case 1:
					startActivity(new Intent(Dashboard.this, MySchedules.class).putExtra("TAG_APPROVAL", approval));
					break;
				case 2:
					getFriendsList();
					break;
				case 3:
					startActivity(new Intent(Dashboard.this, LauncherTeacher.class));
					break;
				case 4:
					startActivity(new Intent(Dashboard.this, Attendance.class));
					break;
			}
		}
		
		if (getRole() == 1) {
			switch (position) {
				case 0:
					startActivity(new Intent(Dashboard.this, ActivityManager.class));
					break;
				case 1:
					startActivity(new Intent(Dashboard.this, LauncherStudent.class));
					break;
				case 2:
					getFriendsList();
					break;
				case 3:
					startActivity(new Intent(Dashboard.this, OverAllRating.class));
					break;
			}
		}
		
	}
	
	private long lastPress;
	@Override
	public void onBackPressed() {
		
	    long currentTime = System.currentTimeMillis();
	    
	    if (currentTime - lastPress > 3500){
	    	TextView msg = new TextView(this);
			msg.setText("You will be logged out of the system!");
			msg.setTextAppearance(Dashboard.this, R.style.alert_message);
			msg.setGravity(Gravity.CENTER_HORIZONTAL);

			new AlertDialog.Builder(this)
			.setTitle("Alert!").setView(msg)
			.setIcon(android.R.drawable.ic_dialog_alert).setCancelable(false)
			.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog,int id) {
					startActivity(new Intent (Dashboard.this, Login.class));
					finish();
				}
			})
			.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog,int id) {
					dialog.cancel();
				}
			}).create().show();
	        lastPress = currentTime;
	    } else {
	    	unbindService(mConnection);
	        super.onBackPressed();
	    }
	}
	
	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();
		Window window = getWindow();
		window.setFormat(PixelFormat.RGBA_8888);
	}
	
	@Override
	protected void onPause() {
		unbindService(mConnection);
		super.onPause();
	}

	@Override
	protected void onResume() {
		bindService(new Intent(Dashboard.this, IMService.class), mConnection, Context.BIND_AUTO_CREATE);
		
		if (getRole() == 0) {
			menu.setAdapter(new MenuItem(this, R.layout.commons_dashboard_panel_item, MENU_TEACHER));
			
			
			try {
				
				String d = new AsynchronousTask().execute().get();
				
				if (d != null) {
					approval = Integer.valueOf(d);
				}
				
			} catch (InterruptedException e) {
				Toast.makeText(getApplicationContext(), "error : " + e.getClass().toString(), Toast.LENGTH_SHORT).show();
			} catch (ExecutionException e) {
				Toast.makeText(getApplicationContext(), "error : " + e.getClass().toString(), Toast.LENGTH_SHORT).show();
			} catch (NullPointerException e) {
				Toast.makeText(getApplicationContext(), "error : " + e.getClass().toString(), Toast.LENGTH_SHORT).show();
			}
			
		} else {
			menu.setAdapter(new MenuItem(this, R.layout.commons_dashboard_panel_item, MENU_STUDENT));
		}
		
		super.onResume();
	}
	
	private class AsynchronousTask extends AsyncTask<String, String, String> {
		
		protected void onPreExecute() {
			super.onPreExecute();
		}

		protected String doInBackground(String... args) {
			try {
				
					ResultSet rs = DatabaseConnector.getStatement().executeQuery(
							"SELECT SUM((SELECT COUNT(gradesheet.id) FROM gradesheet"
				    				 + " WHERE gradesheet.sid = schedule.id AND gradesheet.isApproved = 0)) AS 'approval'"
				    				 + " FROM schedule"
				    				 + " INNER JOIN curriculum ON curriculum.id = schedule.cid"
				    				 + " WHERE schedule.uid = " + getUserID());

					while (rs.next()) {
						return rs.getString("approval");
					}

			} catch (SQLException e) {
				DatabaseConnector.Logger(getClass(), "doInBackground", e);
			} 

			return null;
		}

		protected void onPostExecute(String postExecute) {
			
			runOnUiThread(new Runnable() {

				public void run() { }
			});
			
		}
		
	}

	// ============================================================= IM Service

	public static final String AUTHENTICATION_FAILED = "0";
	public static final String FRIEND_LIST = "FRIEND_LIST";

	private IAppManager imService;

	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			// This is called when the connection with the service has been
			// established, giving us the service object we can use to
			// interact with the service. Because we have bound to a explicit
			// service that we know is running in our own process, we can
			// cast its IBinder to a concrete class and directly access it.
			imService = ((IMService.IMBinder) service).getService();

			if (imService.isUserAuthenticated() == true) {
				// startActivity(new Intent(Dashboard.this, FriendList.class));
			}
		}

		public void onServiceDisconnected(ComponentName className) {
			// This is called when the connection with the service has been
			// unexpectedly disconnected -- that is, its process crashed.
			// Because it is running in our same process, we should never
			// see this happen.
			imService = null;
			Toast.makeText(Dashboard.this, "IMService Stopped.",
					Toast.LENGTH_SHORT).show();
		}
	};

	public void getFriendsList() {

		if (imService == null) {
			// showDialog(NOT_CONNECTED_TO_SERVICE);
			Toast.makeText(Dashboard.this, "Service unavailable.",
					Toast.LENGTH_SHORT).show();
			return;
		} else if (imService.isNetworkConnected() == false) {
			// showDialog(NOT_CONNECTED_TO_NETWORK);
			Toast.makeText(Dashboard.this, "Network not found.",
					Toast.LENGTH_SHORT).show();
		}
		Thread loginThread = new Thread() {
			private Handler handler = new Handler();

			@Override
			public void run() {

				String result = imService.authenticateUser(getUsername(), getPassword());
				if (result == null || result.equals(AUTHENTICATION_FAILED)) {
					/*
					 * Authentication failed, inform the user
					 */
					handler.post(new Runnable() {
						public void run() {
							// Toast.makeText(Dashboard.this,
							// "An error occurred.",
							// Toast.LENGTH_SHORT).show();
							Log.e("AUTHENTICATION FAILED",
									"Authentication failed: "
											+ getUsername() + " , "
											+ getPassword());
						}
					});

				} else {

					/*
					 * if result not equal to authentication failed, result
					 * is equal to friend list of the user
					 */
					handler.post(new Runnable() {
						public void run() {
							startActivity(new Intent(Dashboard.this,
									FriendList.class));
						}
					});

				} // end else

			}
		};
		loginThread.start();

	}

	
}